package main

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"golang.org/x/crypto/bcrypt"
	"log"
	"net/http"
)

func hashEncode(pwd string) (string, error) {
	hash, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
	if err != nil {
		return "", err
	}
	return string(hash), nil
}

func comparePasswords(hashedPwd string, sourcePwd string) bool {
	err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(sourcePwd))
	if err != nil {
		return false
	}
	return true
}

func conncetsql() *sql.DB {
	var (
		hostIP = "localhost"
		userna = "root"
		passwd = "******"
		datadb = "liluo"
	)
	db, err := sql.Open("mysql", userna+":"+passwd+"@tcp("+hostIP+")/"+datadb+"?charset=utf8")
	if err != nil {
		fmt.Println("错误")
		return nil
	}
	err = db.Ping()
	if err != nil {
		fmt.Println("连接失败")
		return nil
	}
	fmt.Println("数据库连接成功")
	return db
}

func getUser(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	//fmt.Println(r.Form)
	ids := r.Form["ids"]
	pass := r.Form["password"]
	rows, err := conncetsql().Query("select * from liluo where id = " + ids[0])
	if err != nil {
		fmt.Printf("%s query failed,err:%v\n", err)
		fmt.Fprintf(w, "用户名或者密码错误")
	}
	var id int
	var username string
	var password string
	var notes string
	var heads string
	for rows.Next() {
		err = rows.Scan(&id, &username, &password, &notes, &heads)
		chechErr(err)
	}
	chechErr(err)
	sourcePwd := pass[0]
	pwdMatch := comparePasswords(password, sourcePwd)
	if pwdMatch {
		fmt.Println(username + "登录成功")
		fmt.Fprint(w, "sess")
	} else {
		fmt.Println("密码错误")
		fmt.Fprintf(w, "用户名或者密码错误")
	}
}

func insertUser(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	ids := r.Form["ids"]
	pass := r.Form["password"]
	username := r.Form["username"]
	notes := r.Form["notes"]
	heads := r.Form["heads"]
	rows, err := conncetsql().Prepare("insert into liluo (`id`,`username`,`password`,`notes`,`heads`) values (?,?,?,?,?)")
	if err != nil {
		fmt.Fprintf(w, "err")
		fmt.Println(err)
	}

	hash, err := hashEncode(pass[0])
	if err != nil {
		fmt.Println(err)
	}
	res, err := rows.Exec(ids[0], username[0], hash, notes[0], heads[0])
	datacc, err := res.RowsAffected()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Fprint(w, "sess")
		fmt.Println(datacc)
	}
}

func updateUser(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	ids := r.Form["ids"]
	username1 := r.Form["username"]
	pass1 := r.Form["password"]
	notes1 := r.Form["notes"]
	setdata := r.Form["setdata"]
	fmt.Println(ids[0])
	if setdata[0] == "username" {
		rows, err := conncetsql().Prepare("update liluo set username = ? where id = ?")
		chechErr(err)
		res, err := rows.Exec(username1[0], ids[0])
		if err != nil {
			fmt.Println(err)
			fmt.Fprint(w, "err")
		} else {
			fmt.Println(res)
			fmt.Println(ids[0] + "" +
				" ")
			fmt.Fprint(w, "sess")
		}
	} else if setdata[0] == "password" {
		hash, err := hashEncode(pass1[0])
		if err != nil {
			fmt.Println(err)
		}
		rows, err := conncetsql().Prepare("update liluo set password = ? where id = ?")
		chechErr(err)
		res, err := rows.Exec(hash, ids[0])
		if err != nil {
			fmt.Println(err)
			fmt.Fprint(w, "err")
		} else {
			fmt.Println(res)
			fmt.Println(ids[0] + "修改密码成功")
			fmt.Fprint(w, "sess")
		}
	} else if setdata[0] == "notes" {
		rows, err := conncetsql().Prepare("update liluo set notes = ? where id = ?")
		chechErr(err)
		res, err := rows.Exec(notes1[0], ids[0])
		if err != nil {
			fmt.Println(err)
			fmt.Fprint(w, "err")
		} else {
			fmt.Println(res)
			fmt.Println(ids[0] + "修改权限成功")
			fmt.Fprint(w, "sess")
		}
	}
}

func chechErr(err error) {
	if err != nil {
		panic(err)
	}
}

func main() {
	http.HandleFunc("/user/get", getUser)
	http.HandleFunc("/user/set", insertUser)
	http.HandleFunc("/user/update", updateUser)
	err := http.ListenAndServe(":9090", nil)
	if err != nil {
		log.Fatal("ListenAndServe:", err)
	}
}
